/*
 * MediaPacket.cpp
 *
 *  Created on: 2016年1月12日
 *      Author: terry
 */

#include "MediaPacket.h"
#include "Ffmpeg.h"


namespace av
{

MediaPacket::MediaPacket():
		m_avpkt(),
		m_type()
{
	m_avpkt = new AVPacket();
	av_init_packet(m_avpkt);
}

MediaPacket::~MediaPacket()
{
	cleanup();
}

MediaPacket::MediaPacket(const MediaPacket& obj):
		m_avpkt(),
		m_type(obj.m_type)
{
	m_avpkt = new AVPacket();
	av_init_packet(m_avpkt);
	av_packet_ref(m_avpkt, obj.m_avpkt);
}

MediaPacket& MediaPacket::operator = (const MediaPacket& obj)
{
	av_packet_unref(m_avpkt);

	av_packet_ref(m_avpkt, obj.m_avpkt);

	m_type = obj.m_type;

	return *this;
}

void MediaPacket::reset()
{
	av_packet_unref(m_avpkt);
}

MediaPacket MediaPacket::clone()
{
	MediaPacket pkt;
	pkt.clone(m_avpkt);
	return pkt;
}

MediaPacket& MediaPacket::clone(const MediaPacket& obj)
{
	av_copy_packet(m_avpkt, obj.m_avpkt);
	return *this;
}

AVPacket* MediaPacket::get()
{
	return m_avpkt;
}

MediaPacket::MediaPacket(AVPacket* avpkt):
		m_avpkt(avpkt),
		m_type()
{
	if (!m_avpkt)
	{
		m_avpkt = new AVPacket();
		av_init_packet(m_avpkt);
	}
}

MediaPacket& MediaPacket::operator = (AVPacket* avpkt)
{
	return ref(avpkt);
}

MediaPacket& MediaPacket::ref(AVPacket* avpkt)
{
	if (avpkt)
	{
		av_packet_ref(m_avpkt, avpkt);
	}
	else
	{
		av_packet_unref(m_avpkt);
	}
	return *this;
}

MediaPacket& MediaPacket::clone(AVPacket* avpkt)
{
	if (avpkt)
	{
		av_copy_packet(m_avpkt, avpkt);
	}
	else
	{
		av_packet_unref(m_avpkt);
	}
	return *this;
}




void MediaPacket::cleanup()
{
	if (m_avpkt)
	{
		av_free_packet(m_avpkt);
		delete m_avpkt;
		m_avpkt = NULL;
	}
}

uint8_t * MediaPacket::data() const
{
	return m_avpkt->data;
}

int MediaPacket::size() const
{
	return m_avpkt->size;
}

int64_t MediaPacket::pts() const
{
	return m_avpkt->pts;
}

int64_t MediaPacket::dts() const
{
	return m_avpkt->dts;
}

int MediaPacket::stream_index() const
{
	return m_avpkt->stream_index;
}

int MediaPacket::flags() const
{
	return m_avpkt->flags;
}

int MediaPacket::duration() const
{
	return m_avpkt->duration;
}

int64_t MediaPacket::pos() const
{
	return m_avpkt->pos;
}


void MediaPacket::set_pts(int64_t val)
{
	m_avpkt->pts = val;
}

void MediaPacket::set_dts(int64_t val)
{
	m_avpkt->dts = val;
}

void MediaPacket::set_stream_index(int val)
{
	m_avpkt->stream_index = val;
}

void MediaPacket::set_flags(int val)
{
	m_avpkt->flags = val;
}

void MediaPacket::set_duration(int val)
{
	m_avpkt->duration = val;
}

void MediaPacket::set_pos(int64_t val)
{
	m_avpkt->pos = val;
}

int MediaPacket::copy_props(AVPacket* src)
{
	return av_packet_copy_props(m_avpkt, src);
}

int MediaPacket::copy_props(MediaPacket& src)
{
	return copy_props(src.m_avpkt);
}

void MediaPacket::setData(uint8_t* data, int size)
{
	m_avpkt->data = data;
	m_avpkt->size = size;
}

int MediaPacket::copy(const AVPacket *src)
{
	return av_copy_packet(m_avpkt, src);
}

int MediaPacket::grow(int grow_by)
{
	return av_grow_packet(m_avpkt, grow_by);
}

void MediaPacket::shrink(int size)
{
	av_shrink_packet(m_avpkt, size);
}

int MediaPacket::new_packet(int size)
{
	return av_new_packet(m_avpkt, size);
}

void MediaPacket::free_packet()
{
	av_free_packet(m_avpkt);
}

int MediaPacket::type() const
{
	return m_type;
}

void MediaPacket::set_type(int val)
{
	m_type = val;
}

bool MediaPacket::isVideo() const
{
	return (m_type == MEDIA_TYPE_VIDEO);
}

bool MediaPacket::isKey() const
{
    return (flags() & AV_PKT_FLAG_KEY) != 0;
}

bool MediaPacket::empty() const
{
    return size() == 0;
}

bool MediaPacket::ensure(size_t size)
{
	if (m_avpkt->size == 0)
	{
		return 0 == new_packet(size);
	}
	else
	{
		return 0 == grow(size);
	}
}

bool MediaPacket::copy(uint8_t* data, int size)
{
	if (!ensure(size))
	{
		return false;
	}

	memcpy(m_avpkt->data, data, size);
	m_avpkt->size = size;

	return true;
}



} /* namespace av */
